﻿using POC.Configuration;

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using wlog.Model;

namespace wlog.Shell
{
    public abstract class Command : ICommand
    {
        public string[] CommandArgs;
        public string CommnadName { get; set; }

        protected string commandObjectType; // table
        protected string commandVerb; // create 
        protected string objectName; // tablename

        public abstract void Setup(string[] args);
        protected StringDictionary additionalCommands = new StringDictionary();
        // Should make it thread synchrounous
        OutputChannel _results = new OutputChannel();
        public OutputChannel Results
        {
            get
            {   
                return _results;
            }
        }
        Action<string> _outputLine;
        public void OnAddLine(Action<string> addLine)
        {
            _results.OnAddLine += _results_OnAddLine;
            _outputLine = addLine;
        }

        void _results_OnAddLine(string line)
        {
            if (_outputLine != null)
            {
                _outputLine.Invoke(line);
            }
        }
        Task _activity; 
        Action _task;
        public bool WaitForCompletion = false;
        public Command(bool async = false)
        {
            WaitForCompletion = async;
        }
        protected void TokenizeCommand(string [] args, int fromIndex=3)
        {
            this.CommandArgs = args;
            commandVerb = args[0].Trim('"').ToLower();//list/create/update/delete/get
            commandObjectType = args.Length > 1 ? args[1].Trim('"').ToLower() : string.Empty; //table/queue/blob
            objectName = args.Length > 2 ? args[2].Trim('"') : string.Empty; // conainer name


            // objectSource = args.Length > 3 ? args[3].Trim('"') : string.Empty; // options=columnNames / writemode 
            //  objectInstanceUri = args.Length > 4 ? args[4].Trim('"') : string.Empty; // file=uri??

            if (args.Length > fromIndex)
            {
                for (int arg = fromIndex; arg < args.Length; arg++)
                {
                    try
                    {
                        string equalarg = args[arg].Trim().Replace("\\=", "&equals;");
                        if (!string.IsNullOrEmpty(equalarg))
                        {
                            string[] keypars = equalarg.Split("=".ToCharArray());
                            if (keypars.Length == 2)
                            {
                                additionalCommands.Add(keypars[0].ToLower(), keypars[1].Replace("&equals;", "="));
                            }
                        }
                    }
                    catch (Exception jdps)
                    {
                        Results.Add("Some error in parsing commands");
                    }
                }
            }
        }
        protected virtual void CreateTask(Action action)
        {
            _task = action;
        }
        public virtual Task Execute()
        {           
            try
            {
                if (_task == null)
                {
                    _task = new Action(() => { Console.WriteLine("no task"); });
                }
                _activity = new Task(_task);
                //_activity.Start();
                _activity.RunSynchronously();
                /*
                if (Async)
                {   
                    _task.BeginInvoke(null, null);
                }
                else
                {
                    _task.Invoke();
                    
                }
                 * */
            }
            catch (Exception poocx)
            {
            }
            return _activity;
        }

    }
}
